﻿using System;
using System.Collections.Generic;
using System.Text;

namespace System.Data
{
    /// <summary>
    /// 命令信息
    /// </summary>
    public class CommandInfo
    {
        #region CommandText

        private string _commandText = string.Empty;
        /// <summary>
        /// 获取或设置针对数据源运行的文本命令。
        /// </summary>
        public string CommandText
        {
            get
            {
                if (_commandText == null)
                    _commandText = string.Empty;
                return _commandText;
            }
            set { _commandText = value; }
        }

        #endregion

        #region CommandTimeout

        /// <summary>
        /// 获取或设置在终止执行命令的尝试并生成错误之前的等待时间。
        /// </summary>
        public int? CommandTimeout { get; set; }

        #endregion

        #region CommandType

        /// <summary>
        /// 指示或指定如何解释 System.Data.IDbCommand.CommandText 属性。
        /// </summary>
        public System.Data.CommandType? CommandType { get; set; }

        #endregion

        #region Parameters

        private List<IDataParameter> _parameters;
        /// <summary>
        /// 
        /// </summary>
        public List<IDataParameter> Parameters
        {
            get
            {
                if (_parameters == null)
                    _parameters = new List<IDataParameter>();
                return _parameters;
            }
            set { _parameters = value; }
        }


        #endregion

        #region Connection

        /// <summary>
        /// 获取或设置 System.Data.IDbCommand 的此实例使用的 System.Data.IDbConnection。
        /// </summary>
        public System.Data.IDbConnection Connection { get; set; }

        #endregion

        #region Transaction

        /// <summary>
        /// 获取或设置在其中执行 .NET Framework 数据提供程序的 Command 对象的事务。
        /// </summary>
        public System.Data.IDbTransaction Transaction { get; set; }

        #endregion

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="cmdType"></param>
        /// <param name="cmdText"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static CommandInfo Create(System.Data.CommandType cmdType, string cmdText, params System.Data.IDataParameter[] args)
        {
            return new CommandInfo() { CommandType = cmdType, CommandText = cmdText, Parameters = new List<System.Data.IDataParameter>(args) };
        }

        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static CommandInfo Create(System.Data.DbFactory factory, string format, params object[] args)
        {
            System.Collections.Generic.List<IDataParameter> parameters = new Collections.Generic.List<IDataParameter>();
            System.Collections.Generic.List<string> formatArgs = new Collections.Generic.List<string>();
            if (args != null && args.Length > 0)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    var param1 = factory.CreateParameter();
                    param1.ParameterName = string.Format("param{0}", i);
                    param1.Value = args[i];

                    //  验证参数名称
                    CommandInfo.ValidParameterName(factory, param1);
                    //  添加
                    parameters.Add(param1);
                    formatArgs.Add(param1.ParameterName);
                }
            }
            string cmdText = string.Format(format, formatArgs.ToArray());
            return new CommandInfo() { CommandText = cmdText, Parameters = parameters };
        }

        /// <summary>
        /// 更新命令对象
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="connection"></param>
        /// <param name="transaction"></param>
        public void UpdateCommand(System.Data.IDbCommand cmd, System.Data.IDbConnection connection = null, System.Data.IDbTransaction transaction = null)
        {
            //  如果命令有效
            if (cmd != null)
            {
                //  更新命令类型
                if (this.CommandType.HasValue)
                    cmd.CommandType = this.CommandType.Value;
                //  更新命令文本
                cmd.CommandText = this.CommandText;
                //  更新命令超时时间
                if (this.CommandTimeout.HasValue)
                    cmd.CommandTimeout = this.CommandTimeout.Value;
                //  如果连接不为空，则绑定连接对象
                if (connection != null)
                {
                    this.Connection = connection;
                    cmd.Connection = connection;
                }
                //  如果事务不为空，则绑定事务对象
                if (transaction != null)
                {
                    this.Transaction = transaction;
                    cmd.Transaction = transaction;
                }
                //  更新命令的参数列表
                if (this.Parameters != null)
                {
                    foreach (IDataParameter parameter in this.Parameters)
                    {
                        CommandInfo.ValidParameterValue(parameter);
                        cmd.Parameters.Add(parameter);
                    }
                }
            }
        }

        /// <summary>
        /// 验证参数名称
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="parameter"></param>
        public static void ValidParameterName(System.Data.DbFactory factory, System.Data.IDataParameter parameter)
        {
            if (parameter != null)
            {
                switch (factory.DatabaseType)
                {
                    case System.Data.DatabaseType.Odbc:
                        break;
                    case System.Data.DatabaseType.OleDb:
                        break;
                    case System.Data.DatabaseType.Access:
                        parameter.ParameterName = "?";
                        break;
                    case System.Data.DatabaseType.Oracle:
                        break;
                    case System.Data.DatabaseType.MySql:
                        parameter.ParameterName = "?";
                        break;
                    case System.Data.DatabaseType.SqlCe:
                        break;
                    case System.Data.DatabaseType.SQLite:
                        parameter.ParameterName = "?";
                        break;
                    default:
                        if (!string.IsNullOrEmpty(parameter.ParameterName) && parameter.ParameterName[0].ToString() != factory.ParameterPrefix)
                            parameter.ParameterName = string.Concat(factory.ParameterPrefix, parameter.ParameterName);
                        break;
                }
            }
        }

        /// <summary>
        /// 验证参数绑定的值
        /// </summary>
        /// <param name="parameter"></param>
        public static void ValidParameterValue(System.Data.IDataParameter parameter)
        {
            if (parameter != null)
            {
                if (parameter.Value == null)
                    parameter.Value = DBNull.Value;
                else if (parameter.Value.GetType() == typeof(System.DateTime))//DateTime
                {
                    if (object.Equals(parameter.Value, System.DateTime.MinValue))//DateTime(DateTime.MinValue)
                        parameter.Value = System.DBNull.Value;
                }
            }
        }
    }
}
